(function() {

    var
    $u = juliet.using({
        validationResult : 'juliet.validation.validationResult',
        validationEvent : 'juliet.validation.validationEvent',
        validator : 'juliet.validation.validator'
    }),
    ve = $u('validationEvent'),
    vr = $u('validationResult');

    /**
     * Verification validator
     */
    var VerifyClass = function() {

        this.initialize = function(o) {
            this.base.initialize.call(this, o);
            this.chain.observer.subscribe('validated', this.chainValidatedEventHandler, this);
        };

        this.getVerifyValidatorIfItActive = function() {
            var verifyValidator = this.metadata.verifyValidator;
            if (verifyValidator.previous && (verifyValidator.previous.result !== vr.SUCCESS)) return null;
            return verifyValidator;
        };

        this.chainValidatedEventHandler = function(o) {
            var verifyValidator = this.getVerifyValidatorIfItActive();

            if (verifyValidator == null) return;

            if (this.getOptionValue('suppressError') && (o.validationEvent == ve.BLUR)) {
                verifyValidator.chain.hideLastError();
            }
        };

        this.validate = function() {
            var
            value = this.chain.fieldValueHelper.fieldValue,
            verifyValidatorChain = this.metadata.verifyValidator.chain,
            verifyValue = verifyValidatorChain.fieldValueHelper.fieldValue;

            this.result = ((value === verifyValue) ? vr.SUCCESS : vr.FAILED);

            if (verifyValue == '') {
                return;
            }

            this.validateVerifyValidatorChain();
        };

        this.validateVerifyValidatorChain = function() {
            var verifyValidator = this.getVerifyValidatorIfItActive();

            if (verifyValidator == null) return;

            verifyValidator.chain.validate({
                currentValidator : verifyValidator,
                validationResult : this.result,
                validationEvent : ve.CHANGE
            });
        };

        this.getError = function() {
            return this.base.getError.call(this, 'verify');
        };

    };

    $u('validator').addValidator('Verify', VerifyClass);

})();
